/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import java.io.IOException;
import java.util.Hashtable;
import tst.TST;
import util.CommonUtil;
import util.FileUtility;

public class KamusEngine implements HttpListener {

    private static final String SERVER_UPDATE = "http://localhost:8084/serverKamus/K_UPDATE";   //address server untuk update
    private static final String SERVER_ADDWORD = "http://localhost:8084/serverKamus/K_NEWWORD"; //address server untuk tambah kata
    private static final String DB_GI = "file:///root1/db_gi.dat";  //alamat data gaul-ind
    private static final String DB_IG = "file:///root1/db_ig.dat";  //alamat data ind-gaul
    public static final byte ORI_GAUL_IND = 0;
    public static final byte ORI_IND_GAUL = 1;
    private static final int MODE_UPDATE = 1;
    private static final int MODE_ADDWORD = 2;
    private TST tst;    //objek ternary search tree
    public DbInfoUpdate dbInfoUpdate;
    public DbNewWord dbNewWord;
    private Http currHttp;
    private KamusParser parser;
    private Hashtable map;

    public KamusEngine() {
        tst = new TST();
        tst.buildTree();    //bangun tree dengan nilai default
        dbInfoUpdate = new DbInfoUpdate();
        dbNewWord = new DbNewWord();
        dbInfoUpdate.load();    //load rms info update
        dbNewWord.load();       //load rms new word
        parser = new KamusParser();
    }

    /**
     * load data dari file database (.dat) yg berisi pasangan kata
     * @param ori
     */
    public void loadData(byte ori) {
        String data = "";
        if (ori == ORI_GAUL_IND) {
            data = FileUtility.readFileCompressed(DB_GI);
        } else if (ori == ORI_IND_GAUL) {
            data = FileUtility.readFileCompressed(DB_IG);
        }
        //split data
        String[] datas = CommonUtil.splitStr(data, "\n");
        //force to remove data from memory
        data = null;
        System.gc();

        tst = new TST();
        tst.buildTree();

        String[] pairData = null;
        for (int i = 0; i < datas.length; i++) {
            pairData = CommonUtil.splitStr(datas[i], "=");
            tst.insert(pairData[0], pairData[1]);
            System.out.println(i + ":" + pairData[0]);
        }
        datas = null;
        pairData = null;
        System.gc();
        //stop splash
        KamusMidlet.midlet.splash.stopTimer();
    }

    /**
     * mencari kata di dalam ternary search tree
     * @param key kata kunci pencarian
     * @return
     */
    public String search(String key) {
        return (String) tst.getValue(key);
    }

    /**
     * proses request update dengan melakukan pengiriman data xml ke server
     */
    public void update() {
        StringBuffer postData = new StringBuffer();
        postData.append("<xml>").append("<date_gi>").append(dbInfoUpdate.getDateGI()).append("</date_gi>").append("<date_ig>").append(dbInfoUpdate.getDateIG()).append("</date_ig>").append("</xml>");
        System.out.println("ISI XML UPDATE =" + postData.toString());
        currHttp = new Http(SERVER_UPDATE, postData.toString(), MODE_UPDATE, this);
        currHttp.start();
    }

    /**
     * proses request add word dengan melakukan pengiriman data xml ke server
     * @param author
     */
    public void uploadNewWord(String author) {
        StringBuffer postData = new StringBuffer();
        postData.append("<xml>").append("<author>").append(author).append("</author>").append("<gaul>").append(dbNewWord.getWordGaul()).append("</gaul>").append("<ind>").append(dbNewWord.getWordInd()).append("</ind>").append("</xml>");
        System.out.println("ISI XML NEW WORD =" + postData.toString());
        currHttp = new Http(SERVER_ADDWORD, postData.toString(), MODE_ADDWORD, this);
        currHttp.start();
    }

    /**
     * jika proses http sukses
     * @param result
     * @param http
     * @param mode
     */
    public void onHttpSuccess(String result, Http http, int mode) {
        try {
            switch (mode) {
                case MODE_UPDATE:
                    destroyHttp(http);
                    map = getContentGzip(result);
                    String[] content = (String [])map.get("content");
                    result = (String)map.get("data");
                    RespUpdate respUpdate = parser.parseUpdate(result, content);
                    if (respUpdate.getCode().equals("0")) {//download gagal
                        KamusMidlet.midlet.showAlert(respUpdate.getMessage());
                    } else if (respUpdate.getCode().equals("1")) {//download salah satu db
                        if (respUpdate.getContentGI() != null) {
                            FileUtility.writeFile(DB_GI, respUpdate.getContentGI().getBytes());
                            dbInfoUpdate.save(respUpdate.getDateGI(), dbInfoUpdate.getDateIG());
                        } else if (respUpdate.getContentIG() != null) {
                            FileUtility.writeFile(DB_IG, respUpdate.getContentIG().getBytes());
                            dbInfoUpdate.save(dbInfoUpdate.getDateGI(), respUpdate.getDateIG());
                        }
                        loadData(KamusMidlet.midlet.orient);
                        KamusMidlet.midlet.showAlert(respUpdate.getMessage());
                    } else if (respUpdate.getCode().equals("2")) {//download semua db
                        FileUtility.writeFile(DB_GI, respUpdate.getContentGI().getBytes());
                        FileUtility.writeFile(DB_IG, respUpdate.getContentIG().getBytes());
                        dbInfoUpdate.save(respUpdate.getDateGI(), respUpdate.getDateIG());
                        loadData(KamusMidlet.midlet.orient);
                        KamusMidlet.midlet.showAlert(respUpdate.getMessage());
                    }
//                    respUpdate=null;
//                    System.gc();
                    break;
                case MODE_ADDWORD:
                    destroyHttp(http);
                    RespAddWord respAddWord = parser.parseAddWord(result);
                    if (respAddWord.getCode().equals("0")) {  //gagal
                        KamusMidlet.midlet.showAlert(respAddWord.getMessage());
                    } else if (respAddWord.getCode().equals("1")) {    //sukses
                        KamusMidlet.midlet.showAlert(respAddWord.getMessage());
                        dbNewWord.clear();
                    }
//                    respAddWord =null;
//                    System.gc();
                    break;
                default:
                    destroyHttp(http);
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * jika proses http gagal
     * @param result
     * @param http
     * @param mode
     */
    public void onHttpFailed(String result, Http http, int mode) {
        switch (mode) {
            default:
                destroyHttp(http);
                KamusMidlet.midlet.showAlert(result);
                break;
        }
    }

    public void destroyHttp(Http http) {
        http = null;
        currHttp = null;
        System.gc();
    }

    /**
     * mendapatkan content gzip dari xml
     * @param data
     * @return string yg telah diambil tag <content></content>
     */
    public static Hashtable getContentGzip(String data) {
        Hashtable map = new Hashtable(2);
        String[] result = new String[2];
        StringBuffer sb = new StringBuffer(data);
        int idxAwal, idxAkhir;
        for (int i = 0; i < 2; i++) {
            idxAwal = sb.toString().indexOf("<content>");
            idxAkhir = sb.toString().indexOf("</content>");
            result[i] = sb.toString().substring(idxAwal + 9, idxAkhir);
            sb.delete(idxAwal, idxAkhir + 10);
        }
        map.put("content", result);
        map.put("data", sb.toString());
        return map;
    }
}
